package com.cyan.note.config;

import com.cyan.note.security.JwtAuthenticationFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * JWT安全配置
 * 基于JWT的认证和授权配置
 * 
 * @author ZhangzhenYu
 * @since 2025-01-14
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor
public class JwtSecurityConfig {
    
    private final JwtAuthenticationFilter jwtAuthenticationFilter;
    
    /**
     * 配置安全过滤链
     */
    @Bean
    public SecurityFilterChain jwtSecurityFilterChain(HttpSecurity http) throws Exception {
        http
            // 禁用CSRF（因为使用JWT）
            .csrf(AbstractHttpConfigurer::disable)
            
            // 禁用CORS（临时，后续可配置）
            .cors(AbstractHttpConfigurer::disable)
            
            // 配置会话管理（无状态）
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            
            // 配置异常处理
            .exceptionHandling(exceptions -> 
                exceptions.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
            )
            
            // 配置请求授权
            .authorizeHttpRequests(auth -> auth
                // 公开访问的接口
                .requestMatchers("/test/**").permitAll()                    // 测试接口
                .requestMatchers("/auth/login", "/auth/logout").permitAll()  // 认证接口
                .requestMatchers("/actuator/**").permitAll()                // Spring Boot监控
                .requestMatchers("/error").permitAll()                     // 错误页面
                .requestMatchers("/favicon.ico").permitAll()               // 网站图标
                
                // 超级管理员专用接口
                .requestMatchers("/api/admin/**").hasRole("SUPER_ADMIN")
                
                // 店长专用接口
                .requestMatchers("/api/manager/**").hasRole("MANAGER")
                
                // 打手专用接口  
                .requestMatchers("/api/worker/**").hasRole("WORKER")
                
                // 需要认证的接口
                .requestMatchers("/auth/validate", "/auth/userinfo").authenticated()
                .requestMatchers("/api/**").authenticated()
                
                // 其他所有请求都需要认证
                .anyRequest().authenticated()
            )
            
            // 添加JWT过滤器
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        
        return http.build();
    }
    
    /**
     * 认证管理器
     */
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }
}